package com.example.demo.controller.mall;

import com.example.demo.entity.Order;
import com.example.demo.service.shop.OrderService;
import com.example.demo.util.result.Result;
import com.example.demo.util.result.ResultUtil;
import com.example.demo.util.wx.WXPayConfig;
import com.example.demo.util.wx.WXPayConstants;
import com.example.demo.util.wx.WXPayRequest;
import com.example.demo.util.wx.WXPayUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by zezhong.shang on 17-8-11.
 */
@Controller
@RequestMapping("/pay/wxpay/")
public class WxPaymentController {
    //**根据订单号生成二维码**//
    private Logger logger = Logger.getLogger(WxPaymentController.class);

    @Autowired
    private OrderService orderService;

    @Autowired
    private WXPayConfig wxPayConfig;

    @GetMapping("/topay")
    public String topay(Long orderId, Model model) {
        model.addAttribute("orderId",orderId);
        return "web/shop/pay/wx_pay";
    }
    @ApiOperation(value = "订单微信支付", httpMethod = "GET",
            protocols = "HTTP", produces = "application/xml", consumes = "application/x-www-form-urlencoded",
            response = String.class,
            notes = "客户端提交订单支付请求，对该API的返回结果不用处理，浏览器将自动跳转至微信支付二维码页面。<br><b>请使用普通表单提交，不能使用ajax异步提交。</b>")
    @RequestMapping(value = "/createqccode/{orderNo}", method = RequestMethod.GET)
    @ResponseBody
    public Result createQcCode(@PathVariable String orderNo, HttpServletResponse response) {
        Order order = null;
        HashMap<String, String> data = new HashMap<String, String>();
        HashMap<String, Object> result = new HashMap<String, Object>();
        WXPayRequest wxPayRequest = new WXPayRequest(this.wxPayConfig);
        try {
            order = orderService.findById(new Long(orderNo));
            if (order == null ) {
                return ResultUtil.error(500,"订单异常");
            }
            if(order.getStatus()!=0) {
                return ResultUtil.error(500,"订单状态异常："+order.getStatus());
            }
            data.put("body", "爱旅行项目订单支付");
            data.put("out_trade_no", order.getOrderNo());
            data.put("device_info", "");
            data.put("total_fee", "1");
            data.put("spbill_create_ip", "47.92.146.135");
//            data.put("notify_url", "http://pb7j8f.natappfree.cc");

            Map<String, String> r = wxPayRequest.unifiedorder(data);
            String resultCode = r.get("result_code");
            if (resultCode.equals("SUCCESS")) {
                result.put("product_id", order.getProduct_id());
                result.put("user_id", order.getUserId());
                result.put("amount", order.getAmount());
                result.put("order_no", order.getOrderNo());
                //微信返回的网址，前端通过qrcode.js生成支付的二维码
                result.put("codeUrl", r.get("code_url"));
                return ResultUtil.success(200,"二维码获取成功",result);
            } else {
                logger.info(r.get("return_msg"));
                return ResultUtil.error(500,r.get("err_code_des"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500,"订单支付异常");
        }
    }
    /***
     * ww
     * 微信支付轮询订单，查看订单是否支付成功
     *
     * @param orderNo
     * @return
     */
    @ApiOperation(value = "订单微信支付刷单程序", httpMethod = "GET",
            protocols = "HTTP", produces = "application/xml", consumes = "application/x-www-form-urlencoded",
            response = String.class,
            notes = "前端用户检测订单是否成功的接口<br>如果订单状态为2则代表订单支付成功<b></b>")
    @RequestMapping(value = "/queryorderstatus/{orderNo}", method = RequestMethod.GET)
    @ResponseBody
    public Result queryOrderIsSuccess(@PathVariable String orderNo) {
        Order order = null;
        try {
            order = orderService.findByOrderNo(orderNo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.success(200,"",order);
    }

    /**
     * 手机扫码支付成功后，微信自动异步回调的网址,
     * 如果你不回复微信平台，微信会一共请求该网址24次
     * url在application.properties中定义
     * @param request
     * @param response
     */
    @RequestMapping(value = "/notify", method = RequestMethod.POST)
//    @ResponseBody
    public void paymentCallBack(HttpServletRequest request, HttpServletResponse response) {
        WXPayRequest wxPayRequest = new WXPayRequest(this.wxPayConfig);
        Map<String, String> result = new HashMap<String, String>();
        Map<String, String> params = null;
        try {
            InputStream inputStream;
            StringBuffer sb = new StringBuffer();
            inputStream = request.getInputStream();
            String s;
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            while ((s = in.readLine()) != null) {
                sb.append(s);
            }
            in.close();
            inputStream.close();
            params = WXPayUtil.xmlToMap(sb.toString());
            logger.info("1.notify-params>>>>>>>>>>>:" + params);
            boolean flag = wxPayRequest.isResponseSignatureValid(params);
            logger.info("2.notify-flag:" + flag);
            if (flag) {
                String returnCode = params.get("return_code");
                logger.info("3.returnCode:" + returnCode);
                if (returnCode.equals("SUCCESS")) {
                    String transactionId = params.get("transaction_id");
                    String outTradeNo = params.get("out_trade_no");
                    /**
                     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
                     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
                     * 3、校验通知中的seller_id（或者seller_email)是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
                     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。
                    */
                    if (!orderService.processed(outTradeNo)) {
                        orderService.paySuccess(outTradeNo, transactionId);
                    }
                    System.out.println("======4.订单：" + outTradeNo + " 交易完成" + ">>>" + transactionId);
                    logger.info("4.订单：" + outTradeNo + " 交易完成" + ">>>" + transactionId);

                } else {
                    result.put("return_code", "FAIL");
                    result.put("return_msg", "支付失败");
                    logger.info("");
                }
                logger.info("5.通知微信，我已经收到结果，不要再发过来了");
                Map<String,String> param = new HashMap<>();
                param.put("return_code","SUCCESS");
                param.put("return_msg","OK");
                String xml = WXPayUtil.generateSignedXml(param, wxPayConfig.getKey(), WXPayConstants.SignType.HMACSHA256);
                System.out.println(xml);
                PrintWriter out =  response.getWriter();
                out.write(xml);//类似于支付宝要求返回一个success字符
                out.close();
            } else {
                result.put("return_code", "FAIL");
                result.put("return_msg", "签名失败");
                logger.info("签名验证失败>>>>>>>>>>>>");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
//        return result;
    }
}
